package com.hetang.maijiayun.adaptertools.utils;

import com.hetang.maijiayun.api.util.B2cBase;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

import java.io.IOException;
import java.text.SimpleDateFormat;

public class JsonUtil {
	private static ObjectMapper om;

	static {
		om = new ObjectMapper();
		om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	}
	
	public static <T> T getBean(String json, Class<T> clazz) throws AdapterException {
		try {
			if(json == null || json.isEmpty())
				return null;

			return om.readValue(json, clazz);
		} catch(JsonParseException je) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, je.getMessage());
		} catch(JsonMappingException me) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, me.getMessage());
		} catch(IOException ie) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, ie.getMessage());
		}
	}
	
	public static <P, T extends TB2cBase, E extends B2cBase> Object getBean(String type, String json, TypeReference<Pair<P, T>> ptReference,
			TypeReference<Pair<T, E>> teReference, TypeReference<E> eReference) throws AdapterException {
		try {
			if(json == null || json.isEmpty())
				return null;

			if(type.equals(Util.PLATFORM_NEW_ADD))
				return om.readValue(json, ptReference);
			else if(type.equals(Util.PLATFORM_DELETE))
				return om.readValue(json, eReference);
			else {
				return om.readValue(json, teReference);
			}
		} catch(JsonParseException je) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, je.getMessage());
		} catch(JsonMappingException me) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, me.getMessage());
		} catch(IOException ie) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, ie.getMessage());
		}
	}
	
	public static String writeAsString(Object t) {
		try {
			return om.writeValueAsString(t);
		} catch(JsonGenerationException je) {
			return "{}";
		} catch(JsonMappingException me) {
			return "{}";
		} catch(IOException ie) {
			return "{}";
		}
	}
	
	public static String getString(JSONObject obj, String key) {
		try {
			return obj.getString(key);
		} catch(JSONException je) {
			return null;
		}
	}
	
	public static String getStringDefaultEmpty(JSONObject obj, String key) {
		try {
			return obj.getString(key);
		} catch(JSONException je) {
			return "";
		}
	}
	
	public static String getStringNotNull(JSONObject obj, String key) throws AdapterException {
		try {
			String str = obj.getString(key);
			if(str.equals(""))
				throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, "string is null key : " + key);
			return str;
		} catch(JSONException je) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, "string does not exist key : " + key);
		}
	}	

	public static JSONObject getJSONObjectNotNull(JSONObject obj, String key) throws AdapterException {
		try {
			return obj.getJSONObject(key);
		} catch(JSONException je) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, "JSONObject does not exist key : " + key);
		}		
	}	

	public static JSONObject getJSONObject(JSONObject obj, String key) {
		try {
			return obj.getJSONObject(key);
		} catch(JSONException je) {
			return null;
		}		
	}	
	
	public static JSONArray getJSONArrayNotNull(JSONObject obj, String key) throws AdapterException {
		try {
			return obj.getJSONArray(key);
		} catch(JSONException je) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, "JSONArray does not exist key : " + key);
		}
	}

	public static JSONArray getJSONArray(JSONObject obj, String key) throws AdapterException {
		try {
			return obj.getJSONArray(key);
		} catch(JSONException je) {
			return null;
		}
	}
	
	public static Integer getInt(JSONObject obj, String key) {
		try {
			return obj.getInt(key);
		} catch(JSONException je) {
			return null;
		}	
	}
	
	public static Integer getIntDefaultZero(JSONObject obj, String key) {
		try {
			return obj.getInt(key);
		} catch(JSONException je) {
			return 0;
		}	
	}	
	
	public static Integer getIntNotNull(JSONObject obj, String key) throws AdapterException {
		try {
			return obj.getInt(key);
		} catch(JSONException je) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, "int does not exist key : " + key);
		}	
	}
	
	public static Long getLong(JSONObject obj, String key) {
		try {
			return obj.getLong(key);
		} catch(JSONException je) {
			return null;
		}	
	}
	
	public static Long getLongDefaultZero(JSONObject obj, String key) {
		try {
			return obj.getLong(key);
		} catch(JSONException je) {
			return 0L;
		}	
	}
	
	public static Long getLongNotNull(JSONObject obj, String key) throws AdapterException {
		try {
			return obj.getLong(key);
		} catch(JSONException je) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, "Long does not exist key : " + key);
		}	
	}
	
	public static Boolean getBooleanDefaultFalse(JSONObject obj, String key) throws AdapterException {
		try {
			return obj.getBoolean(key);
		} catch(JSONException je) {
			return false;
		}
	}
	
	public static Boolean getBooleanNotNull(JSONObject obj, String key) throws AdapterException {
		try {
			return obj.getBoolean(key);
		} catch(JSONException je) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, "boolean does not exist key : " + key);
		}	
	}
	
	public static JSONObject fromObjectNotNull(String str) throws AdapterException {
		try {
			return JSONObject.fromObject(str);
		} catch(JSONException je) {
			throw new AdapterException(AdapterExceptionErrorCode.B2C_DATA_BASE_PARSE_CODE, "fromObject error str : " + str);
		}
	}
}
